package mlp;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.Scanner;

/**
 * Used for parsing examples out of input files and holding each example's
 * classification with the example itself
 */
public class MlpExamples {
	
	final private static int CLASSES  = 10;
	private ArrayList<float[]> input;
	private ArrayList<float[]> output;
	private int classify;
	
	public MlpExamples(String trainSetFileName)
	{
		Scanner scan = null;
		try {
			scan = new Scanner(new File(trainSetFileName));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		input = new ArrayList<float[]>();
		output = new ArrayList<float[]>();
		String line;
		int cls;
		while(scan.hasNext())
		{
			line = scan.nextLine();
			cls = Integer.parseInt(line.substring(0,1));
			String[] inputsStr = line.substring(2).split(",");
			float[] inputs = new float[inputsStr.length];
			for(int i =0 ; i < inputsStr.length ; i++){inputs[i] = Float.parseFloat(inputsStr[i]);}
			input.add(inputs);
			output.add(getClsArray(cls));
		}
		scan.close();
	}
	
	public MlpExamples(String trainSetFileName, int classify) {
		
		this.classify = classify;
		
		Scanner scan = null;
		try {
			scan = new Scanner(new File(trainSetFileName));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		input = new ArrayList<float[]>();
		output = new ArrayList<float[]>();
		String line;
		int cls;
		while(scan.hasNext())
		{
			line = scan.nextLine();
			cls = Integer.parseInt(line.substring(0,1));
			
			String[] inputsStr = line.substring(2).split(",");
			float[] inputs = new float[inputsStr.length];
			for(int i =0 ; i < inputsStr.length ; i++){inputs[i] = Float.parseFloat(inputsStr[i]);}
			input.add(inputs);
			output.add(getClsArrayBinary(cls));
		}
		scan.close();
	}
	
	public ArrayList<float[]> getInput() {
		return input;
	}

	
	public MlpExamples(String trainSetFileName, int fromRow, int amount)
	{
		Scanner scan = null;
		try {
			scan = new Scanner(new File(trainSetFileName));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		input = new ArrayList<float[]>();
		output = new ArrayList<float[]>();
		String line = "";
		int cls;
		for(int i=0 ; i < fromRow ; ++i)
		{
			try {
				scan.nextLine();				
			} catch (NoSuchElementException e1) {
				scan.close();
				try {
					scan = new Scanner(new File(trainSetFileName));
				} catch (FileNotFoundException e2) {
					e2.printStackTrace();
					System.out.println("Initializing scanner- reached i = " + i + ", but could not open a new scanner");
					break;
				}
			}
		}
		for(int i=fromRow ; i < amount ; ++i)
		{

			try {
				
				line = scan.nextLine();
				
			} catch (NoSuchElementException e1) {
				scan.close();
				try {
					scan = new Scanner(new File(trainSetFileName));
				} catch (FileNotFoundException e2) {
					e2.printStackTrace();
					System.out.println("Second loop- reached i = " + i + ", but could not open a new scanner");
					break;
				}
			}
			
			cls = Integer.parseInt(line.substring(0,1));
			String[] inputsStr = line.substring(2).split(",");
			float[] inputs = new float[inputsStr.length];
			for(int j =0 ; j < inputsStr.length ; j++){inputs[j] = Float.parseFloat(inputsStr[j]);}
			input.add(inputs);
			output.add(getClsArray(cls));
		}
		scan.close();
	}

	public MlpExamples(String trainSetFileName, int fromRow, int amount, int classify)
	{
		this.classify = classify;
		Scanner scan = null;
		try {
			scan = new Scanner(new File(trainSetFileName));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		input = new ArrayList<float[]>();
		output = new ArrayList<float[]>();
		String line = "";
		int cls;
		for(int i=0 ; i < fromRow ; ++i)
		{
			try {
				scan.nextLine();				
			} catch (NoSuchElementException e1) {
				scan.close();
				try {
					scan = new Scanner(new File(trainSetFileName));
				} catch (FileNotFoundException e2) {
					e2.printStackTrace();
					System.out.println("Initializing scanner- reached i = " + i + ", but could not open a new scanner");
					break;
				}
			}
		}
		for(int i=fromRow ; i < amount ; ++i)
		{

			try {
				
				line = scan.nextLine();
				
			} catch (NoSuchElementException e1) {
				scan.close();
				try {
					scan = new Scanner(new File(trainSetFileName));
				} catch (FileNotFoundException e2) {
					e2.printStackTrace();
					System.out.println("Second loop- reached i = " + i + ", but could not open a new scanner");
					break;
				}
			}
			
			cls = Integer.parseInt(line.substring(0,1));
			String[] inputsStr = line.substring(2).split(",");
			float[] inputs = new float[inputsStr.length];
			for(int j =0 ; j < inputsStr.length ; j++){inputs[j] = Float.parseFloat(inputsStr[j]);}
			input.add(inputs);
			output.add(getClsArrayBinary(cls));
		}
		scan.close();
	}
	
	public ArrayList<float[]> getOutput() {
		return output;
	}
	
	public int size()
	{
		return input.size();
	}

	private float[] getClsArray(int cls)
	{
		float[] arr = new float[CLASSES];
		for(int i = 0 ; i < CLASSES ; ++i)
		{
			arr[i] = i != cls ? -1 : 1; 
		}
		return arr;				
	}
	
	private float[] getClsArrayBinary(int cls)
	{
		float[] arr = new float[1];
		arr[0] = classify == cls ? Mlp.POSITIVE : Mlp.NEGATIVE; 
		return arr;				
	}

}
